import openpyxl
import time

from Tool.YamlHandler import YamlHandler
from Tool.PathBuilder import PathBuilder
from core.Comparison import Comparison


class Transform:
    def __init__(self, xlsxFile):
        # 读取yaml数据
        self.pathReader = PathBuilder('Tool')
        self.path = self.pathReader.joinFullPath('data', 'staffing.yaml')
        self.config = YamlHandler().reader(self.path)

        # 读取excel
        self.listPath = self.pathReader.joinFullPath('bugList', xlsxFile)
        self.workbook = openpyxl.load_workbook(self.listPath)
        self.sheet = self.workbook.active
        self.maxRow = self.sheet.max_row

        # 存储处理后的excel
        self.newWorkbook = openpyxl.Workbook()
        self.newSheet = self.newWorkbook.active

        # 比较数据
        self.oldData = Comparison()

    # 处理原始的BugList
    def _initBugInfo(self):
        # 移除多余的行 获取有需要的列数据
        removeInvalidRows = [1, 2, 3, self.maxRow]
        # 存储处理后的excel文件
        for row_index, row in enumerate(self.sheet.iter_rows(values_only=True), start=1):
            if row[0] is not None and row_index not in removeInvalidRows:
                self.newSheet.append(row)

    # 获取处理后的BugList存放在数组中
    def _processBugInfo(self):
        self._initBugInfo()
        dataList = []
        for row in self.newSheet.iter_rows(min_row=2):
            currentRowData = {}
            for cell in row:
                key = self.newSheet.cell(row=1, column=cell.column).value
                value = cell.value
                currentRowData[key] = value
            dataList.append(currentRowData)

        self.newWorkbook.close()
        return dataList

    # 日期处理
    def _dateChange(self, date):
        """
        :param date: 原始的create_time
        :return: 转换出符合要求的时间格式
        """
        monthList = ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']

        # 26/十月/23 11:06 上午 => 2023-10-26 11:06:00
        timeList = str(date).split(' ')
        dateList = timeList[0].split('/')
        if dateList[1] in monthList:
            month = str(monthList.index(dateList[1]) + 1).zfill(2)
            fullDate = f"{20}{dateList[2]}/{month}/{dateList[0]} {timeList[1]}"
            return fullDate

    # 版本匹配
    def _setVersion(self, projectModule, version):
        """
        :param projectModule: 所属项目
        :param version: bug单的版本信息
        :return:
        """
        for row in self.config[projectModule]['releases']:
            if version in row:
                return self.config[projectModule]['releases'][0][row.index(version) - 1]
        print('当前数据无匹配的版本号，请查询数据源是否配置正确')
        return ''

    # 测试环境判断
    def _setTestEnv(self, *envInfos):
        """
        :param envInfos: 从'Environment found in'/'环境' 中获取准确的bug环境
        :return: bug所在环境
        """
        if all(envInfo == "" for envInfo in envInfos):
            print('当前数据无匹配的环境，请查询数据源是否配置正确')
            return ''
        else:
            for envInfo in envInfos:
                if str(envInfo).upper() in str(self.config['env']).upper():
                    return str(envInfo).upper()

    # 设置缺陷等级
    def _setPriority(self, priority):
        """
        :param priority: bug等级
        :return: 转换为适合格式的bug等级
        """
        if priority is not None and str(priority).lower() in str(self.config['priority']).lower():
            return str(priority).lower()
        elif priority is not None and str(priority).lower() not in str(self.config['priority']).lower():
            if priority in self.config['priority']['level']:
                return priority
        else:
            return ''

    # 相关人员设置处理
    def _setPrincipal(self, projectModule, storyID):
        """
        :param projectModule:所属项目
        :param storyID: 需求id
        :return: 处理人+测试人员
        """
        # 判断存不存在storyID => 存在走对应 不存在走默认值
        if storyID is None or '':
            return self.config[str(projectModule)]['demands']['default']
        elif storyID in list(self.config[str(projectModule)]['demands'].keys()):
            return self.config[projectModule]['demands'][storyID]

    # bug所属模块
    def _getOwnModule(self, ownModule, version):
        """
        :param ownModule: 匹配所属项目
        :param version: 匹配版本值
        :return: 项目类型/bug所属项目
        """
        # projectModule = None
        if str(ownModule).lower() in str(self.config['items']).lower():
            return str(ownModule).lower()
        elif str(ownModule).lower() not in str(self.config['items']).lower() or ownModule is None or ownModule == '':
            # 得到所有的jira版本值
            for item in self.config['items']:
                for release in self.config[item]['releases']:
                    # 根据匹配的版本值，返回对应的所属项目
                    if version in release:
                        return str(item).lower()
        else:
            print('当前数据无匹配模块值，请查询数据源是否配置正确')
            return ''

    # 组装bugList
    def _saveBugList(self):
        resultList = self._processBugInfo()
        # 处理数据
        bugList = []
        bugInfo = {}
        for bug in resultList:
            # 先处理 再组装 最后存入表格
            projectModule = self._getOwnModule(bug['模块'], bug['标签'])
            env = self._setTestEnv(bug['Environment found in'], bug['环境'])
            createTime = self._dateChange(bug['创建日期'])
            release = self._setVersion(projectModule, bug['标签'])
            priority = self._setPriority(bug['优先级'])

            bugInfo['env'] = env
            bugInfo['createTime'] = createTime
            bugInfo['release'] = release
            bugInfo['priority'] = priority

            principal = self._setPrincipal(projectModule, bug['Control Story ID'])
            bugInfo['coder'] = principal['coder']
            bugInfo['tester'] = principal['tester']
            bugInfo['creator'] = self.config[str(bug['模块']).lower()]['creator']

            bugInfo['title'] = f"【{env}/{bug['关键字']}】{bug['概要']}"
            bugInfo['content'] = f"""
                Bug 描述：
                {bug['描述']}
                {'-' * 20}
                版本：{release} / 优先级：{priority}
                发现环境：{env}
                创建日期：{createTime}
                链接的问题：{bug['链接的问题']} / 修复的版本：{bug['修复的版本']}
                创建人：{bug['创建者']}
                关联需求：{bug['Control Story ID']}
            """.strip()
            bugList.append(bugInfo)

        return bugList

    def buildBugList(self):
        workbook = openpyxl.Workbook()
        sheet = workbook.active
        # 设置表头的映射关系
        headersMapping = {
            "title": "标题",
            "content": "详细描述",
            "release": "迭代",
            "coder": "处理人",
            "tester": "测试人员",
            "createTime": "Jira创建时间",
            "creator": "创建人"
        }

        headers = ["title", "content", "release", "coder", "tester", "createTime", "creator"]
        sheet.append(headers)
        allBugList = self.oldData.getFinalBugList(self._saveBugList(),
                                                  self.config['timeSet']['overtime'],
                                                  self.config['timeSet']['overdue'])

        header_row = 1
        for bugList in allBugList:
            for header in headers:
                column_index = headers.index(header) + 1
                cell = sheet.cell(row=header_row + 1, column=column_index)
                cell.value = bugList.get(header)

        # 替换表头 否则无法导入到Tapd
        for row in sheet.iter_rows():
            for cell in row:
                if cell.value in headersMapping:
                    cell.value = headersMapping[cell.value]

        # 替换后保存到指定路径
        filename = f'TapdBugList-[{time.strftime("%Y.%m.%d %H.%M.%S")}].xlsx'
        workbook.save(self.pathReader.joinFullPath('bugList', filename))

        print(f"BugList Build Finished ..."
              f"FilePath => 【 {self.pathReader.joinFullPath('bugList', filename)} 】")
